package com.tedu.api.io;

import org.junit.Test;

import java.io.*;

/**流---专门处理传输数据为：文本
 *
 *
 * 高级流---处理文本--->”转换流“
 * ”字符流“：针对读写抽象类【Reader抽象类、Writer抽象类】
 *
 * 节点流与字符流区别：单位进行区分，节点流最小单位：字节
 *                             字符流最小单位：字符【针对文本】
 *
 * 高级流【转换流】功能：处理文本内容
 * 字符流的子实现类：InputStreamReader   继承 Reader抽象类 读入操作
 *                OutputStreamWriter  继承 Writer抽象类 写出操作
 *  高级流--->转换流【字符流】按照功能划分--->处理文本读写操作
 *  功能：处理节点流又可以被其他流处理，类似于“转换器”效果
 */
public class IOSAPI {
    /**
     * 需求：从 API  文件中 写出 osw.txt文件---一行文本
     */
    @Test
    public void testOSW(){
        //1.所有流全部置空  作用：作用域全局
        FileOutputStream fos=null;  //低级流：搬运数据
        OutputStreamWriter osw=null;//高级流：”转换流：套低级流，套其它高级流“
        //2.捕获流的所有异常
        try {
            fos=new FileOutputStream("osw.txt");
            osw=new OutputStreamWriter(fos);  //”转换流：套低级流，套其它高级流“
            //3.转换流中方法：write() 直接写出文本内容，不需要把文本转换为二进制
            //     高级流---转换流---字符流
            osw.write("给张煜炫来个暴击~~");
            osw.write("6\n");//省去传字节数组
            osw.write("张煜炫");//换行

        } catch (FileNotFoundException e){//路径错、文件写错
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 必须关闭  有高级流 关 高级流
            if (osw!=null)
                try {
                    osw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
    /**
     * Writer抽象类---子实现类OutputStreamWriter  字符输出流 以字符形式写出
     * Reader抽象类---子实现类InputStreamReader   字符输入流 不是以字符形式读入
     *                                                    int 二进制值
     *                                                    【无法直接读取字符串】
     * 高级流：针对转换流中InputStreamReader无法直接读入字符串
     * BufferedWriter----直接套在转换流上高级流：缓冲输出流
     * BufferedReader----直接套在转换流上高级流：缓冲输入流
     * 特点：可以按照行形式进行读取字符串【换行文件读取完毕】
     *转换流出现异常：UnsupportedEncodingException编码集转换异常
     *     产生原因：转换流【字符输入/出流】制定编码集不对称
     *             IOException  IO型大异常
     */
    @Test
    public void testISR(){
        //1.流置空---方便后面赋值以及关闭操作
        FileInputStream fis=null;
        InputStreamReader isr=null;//转换流指定编码集，无法读取字符串
        BufferedReader br=null;  //缓冲输入流：解决 读取字符串
        //2.捕获流异常
        try {
            fis=new FileInputStream("osw.txt");
            isr=new InputStreamReader(fis,"GBK");
            //转换流：字符输出流---功能：构造器第二个参数，添加编码集：UTF8 识别文字多：万国码
            br=new BufferedReader(isr);//缓冲输入流
            /**
             * readLine() 读取若干字符串，直到读到读完为止【没有换行符】
             *            读取数据返回值字符串
             * 如果返回值不为null，表示所有数据没有读取完毕
             *           为null，表示所有数据读取完毕【没有换行符】
             */
            //①定义引用类型数量
            String line=null;
            //②【一直】读取一行文本保存line中，判断line不为空---输出文本
            //  (line=br.readLine())!=null
            while ( (line=br.readLine())!=null){
                System.out.println(line);
            }
        } catch (FileNotFoundException e){//文件不存在
            e.printStackTrace();
        } catch (UnsupportedEncodingException e){//编码集异常
            e.printStackTrace();
        } catch (IOException e) {//IO流异常---流最大异常
            e.printStackTrace();
        } finally {
            //关闭流   高级流
            if (br!=null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 作业 2  读取IOSAPI.java文件到控制台
     *         提示：从上到下执行逻辑---标准流：IO+异常捕获
     */
    @Test
    public void testHomeWork2(){
       //1.创建一个低级流---针对 读操作  【路径找到ISOAPI.java】
        FileInputStream fis=null;
        InputStreamReader isr=null;
        BufferedReader br=null;
       //maven项目---src\main\java\com\tedu\api\io\ISOAPI.java
        try {
            fis=new FileInputStream("src"+File.separator+
                    "main"+File.separator+
                    "java"+File.separator+"com"+File.separator+
                    "tedu"+File.separator+
                    "api"+File.separator+"io"+File.separator+"IOSAPI.java");
            //2.创建转换流----指定编码集：UTF8  【不能直接输出字符串】
            isr=new InputStreamReader(fis,"UTF8");
            //3.【能直接输出字符串】创建缓冲？？流
            br=new BufferedReader(isr);
            //4.创建保存每行字符串的变量
            String line=null;
            //5.一直  读取字符串，不等于null 有字符串--同时写出
            while ( (line=br.readLine())!=null){
                System.out.println(line);
            }
            String str=br.readLine();
            System.out.println(str);
        } catch (FileNotFoundException e){
            e.printStackTrace();
        } catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br!=null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 高级流---特殊：①直接创建高级流
     *              ②不是成对---BufferedReader
     *              ③直接写出文本
     * PrintWriter 字符输出流  直接替代 BufferedReader
     * 需求：从程序写出 pw.txt 文件 指定编码集：UTF8,输出几行文本
     */
     @Test
    public void testPW() throws FileNotFoundException, UnsupportedEncodingException {
        //创建高级流:套3个流  FileOutputStream   低级流   搬运数据
         //                OutputStreamWriter  高级流   转换流  制定编码集
         //                BufferedWriter     高级流    套在转换流上  效率写
         PrintWriter pw=new PrintWriter("pw.txt","utf8");
         //print() 输出一行文本，不换行  println()输出一行文本，换行
         pw.print("你就是");
         pw.println("我的小可爱~");
         pw.close();
     }
}
